SQLite でデータを永続化する
大量のデータを永続化してクエリする必要があるアプリを作成している場合、 ローカル デバイスの場合は、ローカル ファイルの代わりにデータベースの使用を検討するか、 キーと値のストア。一般に、データベースはより高速な挿入、更新、 他のローカル永続性ソリューションと比較したクエリ。
Flutter アプリは、sqflite
プラグインは pub.dev で入手できます。
このレシピでは基本的な使い方を説明します。sqflite
さまざまな犬に関するデータを挿入、読み取り、更新、削除します。
SQLite と SQL ステートメントを初めて使用する場合は、「SQLite チュートリアルその前に基礎を学ぶために このレシピを完成させます。
このレシピでは次の手順を使用します。
- 依存関係を追加します。
- を定義します
Dog
データ・モデル。 - データベースを開きます。
- を作成します。
dogs
テーブル。 - を挿入します
Dog
データベースに。 - 犬のリストを取得します。
- 更新
Dog
データベース内で。 - を削除します
Dog
データベースから。
1. 依存関係を追加します
SQLite データベースを操作するには、sqflite
とpath
パッケージ。
- の
sqflite
パッケージはクラスと関数を提供します SQLite データベースと対話します。 - の
path
パッケージは機能を提供します データベースをディスク上に保存する場所を定義します。
パッケージを依存関係として追加するには、
走るflutter pub add
:
$ flutter pub add sqflite path
作業するファイルにパッケージを必ずインポートしてください。
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
2. Dog データモデルを定義する
Dogs に関する情報を保存するテーブルを作成する前に、少し時間を取ってください。
保存する必要があるデータを定義します。この例では、Dog クラスを定義します。
これには 3 つのデータが含まれています。
ユニークid
、name
、 そしてそのage
それぞれの犬の。
class Dog {
final int id;
final String name;
final int age;
const Dog({
required this.id,
required this.name,
required this.age,
});
}
3. データベースを開きます
データベースへのデータの読み取りと書き込みを行う前に、接続を開きます データベースに。これには次の 2 つの手順が含まれます。
- 次を使用してデータベース ファイルへのパスを定義します。
getDatabasesPath()
からsqflite
パッケージと組み合わせて、join
からの関数path
パッケージ。 - 次のコマンドでデータベースを開きます
openDatabase()
からの関数sqflite
。
// Avoid errors caused by flutter upgrade.
// Importing 'package:flutter/widgets.dart' is required.
WidgetsFlutterBinding.ensureInitialized();
// Open the database and store the reference.
final database = openDatabase(
// Set the path to the database. Note: Using the `join` function from the
// `path` package is best practice to ensure the path is correctly
// constructed for each platform.
join(await getDatabasesPath(), 'doggie_database.db'),
);
dogs
テーブル
4.次に、さまざまな Dog に関する情報を保存するテーブルを作成します。
この例では、という名前のテーブルを作成します。dogs
データを定義するもの
保管できるもの。各Dog
が含まれていますid
、name
、 とage
。
したがって、これらは次の 3 つの列として表されます。dogs
テーブル。
- の
id
ダーツですint
として保存されます。INTEGER
SQLite データ・タイプ。を使用することも良い習慣です。id
プライマリとして テーブルのキーを使用して、クエリと更新の時間を短縮します。 - の
name
ダーツですString
として保存されます。TEXT
SQLite データ・タイプ。 - の
age
ダーツでもありますint
として保存されます。INTEGER
データ・タイプ。
に保存できる利用可能なデータ型の詳細については、 SQLite データベースについては、を参照してください。SQLite データ型の公式ドキュメント。
final database = openDatabase(
// Set the path to the database. Note: Using the `join` function from the
// `path` package is best practice to ensure the path is correctly
// constructed for each platform.
join(await getDatabasesPath(), 'doggie_database.db'),
// When the database is first created, create a table to store dogs.
onCreate: (db, version) {
// Run the CREATE TABLE statement on the database.
return db.execute(
'CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)',
);
},
// Set the version. This executes the onCreate function and provides a
// path to perform database upgrades and downgrades.
version: 1,
);
5. データベースに犬を挿入します。
これで、情報の保存に適したテーブルを備えたデータベースが完成しました。 さまざまな犬について、データの読み取りと書き込みを行います。
まず、Dog
にdogs
テーブル。これには次の 2 つの手順が含まれます。
- 変換する
Dog
にMap
- 使用
insert()
を保存する方法Map
の中にdogs
テーブル。
class Dog {
final int id;
final String name;
final int age;
const Dog({
required this.id,
required this.name,
required this.age,
});
// Convert a Dog into a Map. The keys must correspond to the names of the
// columns in the database.
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'age': age,
};
}
// Implement toString to make it easier to see information about
// each dog when using the print statement.
@override
String toString() {
return 'Dog{id: $id, name: $name, age: $age}';
}
}
// Define a function that inserts dogs into the database
Future<void> insertDog(Dog dog) async {
// Get a reference to the database.
final db = await database;
// Insert the Dog into the correct table. You might also specify the
// `conflictAlgorithm` to use in case the same dog is inserted twice.
//
// In this case, replace any previous data.
await db.insert(
'dogs',
dog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
// Create a Dog and add it to the dogs table
var fido = const Dog(
id: 0,
name: 'Fido',
age: 35,
);
await insertDog(fido);
6. 犬のリストを取得する
今では、Dog
データベースに保存されている場合は、データベースにクエリを実行します
特定の犬またはすべての犬のリスト。これには次の 2 つの手順が含まれます。
- を実行します
query
に対してdogs
テーブル。これは、List<Map>
。 - 変換する
List<Map>
にList<Dog>
。
// A method that retrieves all the dogs from the dogs table.
Future<List<Dog>> dogs() async {
// Get a reference to the database.
final db = await database;
// Query the table for all The Dogs.
final List<Map<String, dynamic>> maps = await db.query('dogs');
// Convert the List<Map<String, dynamic> into a List<Dog>.
return List.generate(maps.length, (i) {
return Dog(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
// Now, use the method above to retrieve all the dogs.
print(await dogs()); // Prints a list that include Fido.
Dog
データベース内で
7. を更新しますデータベースに情報を入力した後、
後でその情報を更新することもできます。
これを行うには、update()
からのメソッドsqflite
図書館。
これには次の 2 つの手順が含まれます。
- 犬を地図に変換します。
- 使う
where
句を使用して、正しい Dog を更新するようにしてください。
Future<void> updateDog(Dog dog) async {
// Get a reference to the database.
final db = await database;
// Update the given Dog.
await db.update(
'dogs',
dog.toMap(),
// Ensure that the Dog has a matching id.
where: 'id = ?',
// Pass the Dog's id as a whereArg to prevent SQL injection.
whereArgs: [dog.id],
);
}
// Update Fido's age and save it to the database.
fido = Dog(
id: fido.id,
name: fido.name,
age: fido.age + 7,
);
await updateDog(fido);
// Print the updated results.
print(await dogs()); // Prints Fido with age 42.
Dog
データベースから
8. を削除します犬に関する情報を掲載・更新するほか、
データベースから犬を削除することもできます。データを削除するには、
使用delete()
からのメソッドsqflite
図書館。
このセクションでは、ID を取得して犬を削除する関数を作成します。
データベースからの一致する ID。これを機能させるには、where
削除されるレコードを制限する句。
Future<void> deleteDog(int id) async {
// Get a reference to the database.
final db = await database;
// Remove the Dog from the database.
await db.delete(
'dogs',
// Use a `where` clause to delete a specific dog.
where: 'id = ?',
// Pass the Dog's id as a whereArg to prevent SQL injection.
whereArgs: [id],
);
}
例
例を実行するには:
- 新しい Flutter プロジェクトを作成します。
- を追加します。
sqflite
とpath
あなたへのパッケージpubspec.yaml
。 - 次のコードを新しいファイルに貼り付けます。
lib/db_test.dart
。 - コードを実行します
flutter run lib/db_test.dart
。
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
void main() async {
// Avoid errors caused by flutter upgrade.
// Importing 'package:flutter/widgets.dart' is required.
WidgetsFlutterBinding.ensureInitialized();
// Open the database and store the reference.
final database = openDatabase(
// Set the path to the database. Note: Using the `join` function from the
// `path` package is best practice to ensure the path is correctly
// constructed for each platform.
join(await getDatabasesPath(), 'doggie_database.db'),
// When the database is first created, create a table to store dogs.
onCreate: (db, version) {
// Run the CREATE TABLE statement on the database.
return db.execute(
'CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)',
);
},
// Set the version. This executes the onCreate function and provides a
// path to perform database upgrades and downgrades.
version: 1,
);
// Define a function that inserts dogs into the database
Future<void> insertDog(Dog dog) async {
// Get a reference to the database.
final db = await database;
// Insert the Dog into the correct table. You might also specify the
// `conflictAlgorithm` to use in case the same dog is inserted twice.
//
// In this case, replace any previous data.
await db.insert(
'dogs',
dog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
// A method that retrieves all the dogs from the dogs table.
Future<List<Dog>> dogs() async {
// Get a reference to the database.
final db = await database;
// Query the table for all The Dogs.
final List<Map<String, dynamic>> maps = await db.query('dogs');
// Convert the List<Map<String, dynamic> into a List<Dog>.
return List.generate(maps.length, (i) {
return Dog(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
Future<void> updateDog(Dog dog) async {
// Get a reference to the database.
final db = await database;
// Update the given Dog.
await db.update(
'dogs',
dog.toMap(),
// Ensure that the Dog has a matching id.
where: 'id = ?',
// Pass the Dog's id as a whereArg to prevent SQL injection.
whereArgs: [dog.id],
);
}
Future<void> deleteDog(int id) async {
// Get a reference to the database.
final db = await database;
// Remove the Dog from the database.
await db.delete(
'dogs',
// Use a `where` clause to delete a specific dog.
where: 'id = ?',
// Pass the Dog's id as a whereArg to prevent SQL injection.
whereArgs: [id],
);
}
// Create a Dog and add it to the dogs table
var fido = const Dog(
id: 0,
name: 'Fido',
age: 35,
);
await insertDog(fido);
// Now, use the method above to retrieve all the dogs.
print(await dogs()); // Prints a list that include Fido.
// Update Fido's age and save it to the database.
fido = Dog(
id: fido.id,
name: fido.name,
age: fido.age + 7,
);
await updateDog(fido);
// Print the updated results.
print(await dogs()); // Prints Fido with age 42.
// Delete Fido from the database.
await deleteDog(fido.id);
// Print the list of dogs (empty).
print(await dogs());
}
class Dog {
final int id;
final String name;
final int age;
const Dog({
required this.id,
required this.name,
required this.age,
});
// Convert a Dog into a Map. The keys must correspond to the names of the
// columns in the database.
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'age': age,
};
}
// Implement toString to make it easier to see information about
// each dog when using the print statement.
@override
String toString() {
return 'Dog{id: $id, name: $name, age: $age}';
}
}